/**
  * @addtogroup 
  * 
  *
  * @brief 
  *
  * @code{c}
  * @endcode
  * @{
  * @file         bsc_electric_fence_platform.h
  * @brief        添加平台对象
  * @note
  * @author       Jpz(puzhao.jin@hopechart，靳普诏)
  * @date         2022-09-22
  * @version      1.0
  * 
  * @par          修改日志
  * <table>
  * <tr><th>Date        <th>Version          <th>Author                        <th>Description
  * <tr><td>2022-09-22  <td>1.0              <td>Jpz                           <td>创建初始版本
  * @copyright    杭州鸿泉物联网技术股份有限公司
  */



#ifndef _BSC_ELECTRIC_FENCE_PLATFORM_H_
#define _BSC_ELECTRIC_FENCE_PLATFORM_H_

#include "bsc_electric_fence/bsc_electric_fence_tool_if.h"
#include "bsc_electric_fence/bsc_electric_fence_zone_data.h"

#ifdef __cplusplus
extern "C" {
#endif


enum TBsElectricFencePlatformNotifyTypeTag
{
    kBsElectricFenceChannelNotifyTypeEnterZone      = 0,    // 正常进入区间
    kBsElectricFenceChannelNotifyTypeLeaveZone      = 1,    // 正常离开区间
    kBsElectricFenceChannelNotifyTypeEnterWarning   = 2,  // 禁行时段进入区间
    kBsElectricFenceChannelNotifyTypeLeaveWarning   = 3,  // 禁行时段离开区间
    kBsElectricFenceChannelNotifyTypeOverSpeed      = 4,    // 超速告警

};
typedef enum TBsElectricFencePlatformNotifyTypeTag TBsElectricFencePlatformNotifyType;


/// 当前所在区域临时属性
typedef struct TBsElectricFencePlatformZoneTempAttrTag TBsElectricFencePlatformZoneTempAttr;
struct TBsElectricFencePlatformZoneTempAttrTag
{
    Bool    is_invalid_;        ///< 为True时自动从列表中移除
    UInt8   warring_time_flag_;      ///< 大于 0 时处于 禁行状态
    UInt8   warring_speed_flag_;     ///< 大于 0 时处于 超速状态
    Byte    reserve[1];         ///< 暂做保留
    UInt32  entry_zone_time_;   ///< 进入区域时间戳（unix时间戳，单位 秒）
    UInt32  normal_speed_time_; ///< 最后一次正常速度时间戳（unix时间戳，单位 秒）
    UInt32  warring_time_;      ///< 最后一次上报禁行警告时间戳（unix时间戳，单位 秒）

    /// 用户自定义临时变量
    UInt32  user_param_size_;   ///< 变量大小，由用户设置
    Byte    user_param_[1];     ///< 保证内存连续
};


/// 通知数据结构体
typedef struct TBsElectricFencePlatformNotifyDataTag TBsElectricFencePlatformNotifyData;
struct TBsElectricFencePlatformNotifyDataTag
{
    UInt8 notify_type;      ///< 通知类型 （@ref TBsElectricFencePlatformNotifyTypeTag）
    UInt8 zone_type;        ///< 区域类型  (@ref TBsElectricFenceShape)[@file bsc_electric_fence_zone_data.h]
    TBsElectricFenceMoveStatus *curr_move_status;
    TBsElectricFenceZoneBaseInfo *zone_info;    ///< 区域信息，获取详细信息时需要强转为子类指针
    TBsElectricFencePlatformZoneTempAttr *temp_attr;   ///< 用户自定义临时变量地址
};


/**
 * 函数类型：通知回调，应用通过该回调处理业务  
 * @param *user_params  用户传参 
 * @param *notify_data  通知数据
 * @return 
 */
typedef void (* TBsElectricFencePlatformOnNotify)(void *user_param, TBsElectricFencePlatformNotifyData *notify_data);

/**
 * 函数类型：添加区域信息  
 * @param *user_params  用户传参
 * @param zone_type      区域类型
 * @param *info_buf     区域信息地址
 * @param info_size     区域信息完整大小 （包括 基本信息、区域形状、拓展属性）
 * @return 成功 >  0 , 成功存储信息大小
 *         失败 <= 0
 */
typedef Int32 (* TBsElectricFencePlatformDoAddZone)(void *user_param, UInt8 zone_type, const TBsElectricFenceZoneBaseInfo *info_buf, Int32 info_size);


/**
 * 函数类型：删除区域信息  
 * @param *user_params  用户传参
 * @param zone_type      区域类型
 * @param zone_id        区域id
 * @return 成功 == 0
 *         失败 <  0
 */
typedef Int32 (* TBsElectricFencePlatformDoDeleteZone)(void *user_param, UInt8 zone_type, UInt32 zone_id);


/**
 * 函数类型：修改区域信息  
 * @param *user_params  用户传参
 * @param zone_type      区域类型
 * @param zone_id        修改目标区域id
 * @param *info_buf     区域新信息数据地址
 * @param info_size     数据大小
 * @return 成功 >  0 , 成功存储信息大小
 *         失败 <= 0
 */
typedef Int32 (* TBsElectricFencePlatformDoUpdateZone)(void *user_param, UInt8 zone_type, UInt32 zone_id, const TBsElectricFenceZoneBaseInfo *info_buf, Int32 info_size);


/**
 * 函数类型：查询区域信息  
 * @param *user_params  用户传参
 * @param zone_type      区域类型
 * @param zone_id        区域id
 * @param *info_buf     传出信息缓存
 * @param info_size     缓存大小
 * @return 成功 > 0     传出数据大小
 *         失败 < 0
 */
typedef Int32 (* TBsElectricFencePlatformDoFindZone)(void *user_param, UInt8 zone_type, UInt32 zone_id, TBsElectricFenceZoneBaseInfo *info_buf, Int32 info_size);


/**
 * 函数类型：查询区域数量
 * @param *user_params  用户传参
 * @param zone_type      区域类型
 * @return 成功 >= 0    区域数量
 *         失败 <  0
 */
typedef Int32 (* TBsElectricFencePlatformDoGetZoneCount)(void *user_param, UInt8 zone_type);

/**
 * 函数类型：根据索引查询区域信息  
 * @param *user_params  用户传参
 * @param zone_type      区域类型
 * @param zone_index     索引值
 * @param *info_buf     传出信息缓存
 * @param info_size     缓存大小
 * @return 成功 > 0     传出数据大小
 *         失败 < 0
 */
typedef Int32 (* TBsElectricFencePlatformDoGetZoneInfo)(void *user_param, UInt8 zone_type, UInt32 zone_index, TBsElectricFenceZoneBaseInfo *info_buf, Int32 info_size);


typedef struct TBsElectricFencePlatformTag TBsElectricFencePlatform;

/**
 * 用户自定义----为当前所在区域创建临时变量，用户对target_param进行操作，无需进行内存分配动作
 * @param *self                 平台对象句柄
 * @param *target_param         用户自定义参数头指针
 * @param zone_type             当前区域类型
 * @param *zone_info            当前区域标准信息地址
 * @param *curr_move_status     终端当前位置信息
 * @return 
 */
typedef void (* TBsElectricFencePlatFormDoInitTempAttr)(TBsElectricFencePlatform *self, Byte *target_param, UInt8 zone_type, TBsElectricFenceZoneBaseInfo *zone_info, TBsElectricFenceMoveStatus *curr_move_status);

/**
 * 析构用户参数  
 * @param *self                 平台对象句柄
 * @param *target_param         用户自定义参数头指针
 * @return 
 */
typedef void (* TBsElectricFencePlatFormDoDoneTempAttr)(TBsElectricFencePlatform *self, Byte *target_param);


typedef void (* TBsElectricFencePlatformDoRunTempAttr)(TBsElectricFencePlatform *self, TBsElectricFencePlatformNotifyData *notify_data);

/**
 * 临时参数相关接口类型  
 * @param *self             平台对象句柄
 * @param *notify_data      通知数据
 * @return 
 */
typedef void (* TBsElectricFencePlatformDoTempAttrMethod)(TBsElectricFencePlatform *self, TBsElectricFencePlatformNotifyData *notify_data);


struct TBsElectricFencePlatformTag
{
    void *user_params_;     // 平台自定义 用户传参（可用于传回子类句柄）
    const Byte *name;       // 平台名称（测试 方便标记）
    
    UInt16 warring_time_interval_;      ///< 禁行警报上报间隔时长（默认为0，单位:秒）。为 0 时警报仅上报一次
    UInt16 warring_speed_interval_;     ///< 超速警报上报间隔时长（默认为0，单位:秒）。为 0 时警报仅上报一次

    UInt8 boundary_width_[kBsElectricFenceShapeMax];    ///< 边界宽度，用于过滤边界的反复进入（默认为0，单位:米）

    TBsElectricFencePlatformOnNotify          OnNotify;  // 通知回调 （区域进入、离开）

    TBsElectricFencePlatformDoAddZone         DoAddZone;       ///< 添加区域
    TBsElectricFencePlatformDoDeleteZone      DoDeleteZone;    ///< 删除区域
    TBsElectricFencePlatformDoUpdateZone      DoUpdateZone;    ///< 更新区域
    TBsElectricFencePlatformDoFindZone        DoFindZone;      ///< 查找区域

    TBsElectricFencePlatformDoGetZoneCount    DoGetZoneCount;  ///< 当前区域个数
    TBsElectricFencePlatformDoGetZoneInfo     DoGetZoneInfo;   ///< 通过索引检索区域信息

    /// 用户参数相关操作
    UInt32  zone_temp_attr_size_;
    // TBsElectricFencePlatFormDoInitTempAttr DoInitZoneTempAttr;   ///< 初始化用户所在区域临时变量
    // TBsElectricFencePlatFormDoDoneTempAttr DoDoneZoneTempAttr;   ///< 反初始化用户所在区域临时变量
    // TBsElectricFencePlatformDoRunTempAttr  DoRunOnceTempAttr;    ///< 在区域内遍历一次

    TBsElectricFencePlatformDoTempAttrMethod DoInitZoneTempAttr;   ///< 初始化用户所在区域临时变量
    TBsElectricFencePlatformDoTempAttrMethod DoDoneZoneTempAttr;   ///< 反初始化用户所在区域临时变量
    TBsElectricFencePlatformDoTempAttrMethod DoRunOnceTempAttr;    ///< 在区域内遍历一次 (此时传参中通知类型无效)
};


/**
 * 创建平台对象  
 * @param *self         平台对象句柄
 * @param *user_params  用户携带传参（在回调中将作为传参传入）
 * @return 成功 True
 *         失败 False
 */
Bool TBsElectricFencePlatformCreate(TBsElectricFencePlatform *self, void *user_params);


/**
 * 析构  
 * @param *self 平台对象句柄
 * @return 
 */
void TBsElectricFencePlatformDestroy(TBsElectricFencePlatform *self);



/**
 * 设置临时变量创建方法
 * @param *self                 平台对象句柄
 * @param zone_temp_attr_size   变量空间大小（组件内部用于开辟动态内存）
 * @param DoInitUserParam       变量创建初始化（无需拓展临时变量时 可以为NULL）
 * @param DoDoneUserParam       变量结束反初始化（在保证没有内存泄漏情况下 可以为NULL）
 * @param DoRunOnceTempAttr     过程触发（无操作，可以为NULL）
 * @return 
 * @note 直接通过成员变量赋值好像更方便
 */
void TBsElectricFencePlatformSetUserParamMethod(TBsElectricFencePlatform *self, UInt32  zone_temp_attr_size,
                                               TBsElectricFencePlatformDoTempAttrMethod DoInitUserParam,
                                               TBsElectricFencePlatformDoTempAttrMethod DoDoneUserParam,
                                               TBsElectricFencePlatformDoTempAttrMethod  DoRunOnceTempAttr);

/**
 * 禁行警报上报间隔时长
 * @param *self
 * @param interval  禁行警报上报间隔时长值（默认为0，单位:秒）。为 0 时警报仅上报一次
 * @return 
 */
void TBsElectricFencePlatformSetWarringTimeInterval(TBsElectricFencePlatform *self, UInt16 interval);

/**
 * 超速警报上报间隔时长
 * @param *self
 * @param interval  超速警报上报间隔时长值（默认为0，单位:秒）。为 0 时警报仅上报一次
 * @return 
 */
void TBsElectricFencePlatformSetWarringSpeedInterval(TBsElectricFencePlatform *self, UInt16 interval);


/**
 * 设置边界缓冲宽度
 * @param *self
 * @param zone_type     形状类型
 * @param width         宽度值
 * @return 
 */
void TBsElectricFencePlatformSetBoundaryWidth(TBsElectricFencePlatform *self, UInt8 zone_type, UInt8 width);

/* ~~~~~~~~~~~~~~~~~~~~~~~ 触发接口 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */


void TBsElectricFencePlatformNotify(TBsElectricFencePlatform *self, TBsElectricFencePlatformNotifyData *notify_data);


Int32 TBsElectricFencePlatformAddZone(TBsElectricFencePlatform *self, UInt8 zone_type, const TBsElectricFenceZoneBaseInfo *info_buf, Int32 info_size);

Int32 TBsElectricFencePlatformDeleteZone(TBsElectricFencePlatform *self, UInt8 zone_type, UInt32 zone_id);

Int32 TBsElectricFencePlatformUpdateZone(TBsElectricFencePlatform *self, UInt8 zone_type, UInt32 zone_id, const TBsElectricFenceZoneBaseInfo *info_buf, Int32 info_size);

Int32 TBsElectricFencePlatformFindZone(TBsElectricFencePlatform *self, UInt8 zone_type, UInt32 zone_id, TBsElectricFenceZoneBaseInfo *info_buf, Int32 info_size);

Int32 TBsElectricFencePlatformGetZoneCount(TBsElectricFencePlatform *self, UInt8 zone_type);

Int32 TBsElectricFencePlatformGetZoneInfo(TBsElectricFencePlatform *self, UInt8 zone_type, UInt32 zone_index, TBsElectricFenceZoneBaseInfo *info_buf, Int32 info_size);

void  TBsElectricFencePlatFormInitZoneTempAttr(TBsElectricFencePlatform *self, TBsElectricFencePlatformNotifyData *notify_data);   ///< 初始化用户所在区域临时变量
void  TBsElectricFencePlatFormDoneZoneTempAttr(TBsElectricFencePlatform *self, TBsElectricFencePlatformNotifyData *notify_data);   ///< 反初始化用户所在区域临时变量
void  TBsElectricFencePlatformRunOnceTempAttr(TBsElectricFencePlatform *self, TBsElectricFencePlatformNotifyData *notify_data);    ///< 在区域内遍历一次



#ifdef __cplusplus
}  ///< extern "C" {
#endif


#endif

